//using System.IO;
//using System;

//namespace Iori.AudioPlayer {
//    /// <summary>
//    /// Base class for all WaveStream classes. Derives from stream.
//    /// </summary>
//    public abstract class WaveStream : Stream {
//        /// <summary>
//        /// Retrieves the WaveFormat for this stream
//        /// </summary>
//        public abstract WaveFormat WaveFormat { get; }

//        /// <summary>
//        /// Fill the specified buffer with wave data.
//        /// </summary>
//        /// <param name="buffer">The buffer to fill of wave data.</param>
//        /// <returns>
//        /// the number of bytes written to the buffer.
//        /// </returns>
//        public int Read(IWaveBuffer buffer) {
//            return Read(buffer.ByteBuffer, 0, buffer.ByteBufferCount);
//        }

//        // base class includes long Position get; set
//        // base class includes long Length get
//        // base class includes Read
//        // base class includes Dispose

//        /// <summary>
//        /// We can read from this stream
//        /// </summary>
//        public override bool CanRead { get { return true; } }

//        /// <summary>
//        /// We can seek within this stream
//        /// </summary>
//        public override bool CanSeek { get { return true; } }

//        /// <summary>
//        /// We can't write to this stream
//        /// </summary>
//        public override bool CanWrite { get { return false; } }

//        /// <summary>
//        /// Flush does not need to do anything
//        /// See <see cref="Stream.Flush"/>
//        /// </summary>
//        public override void Flush() { }

//        /// <summary>
//        /// An alternative way of repositioning.
//        /// See <see cref="Stream.Seek"/>
//        /// </summary>
//        public override long Seek(long offset, SeekOrigin origin) {
//            if (origin == SeekOrigin.Begin)
//                Position = offset;
//            else if (origin == SeekOrigin.Current)
//                Position += offset;
//            else
//                Position = Length + offset;
//            return Position;
//        }

//        /// <summary>
//        /// Sets the length of the WaveStream. Not Supported.
//        /// </summary>
//        /// <param name="length"></param>
//        public override void SetLength(long length) {
//            throw new NotSupportedException("Can't set length of a WaveFormatString");
//        }

//        /// <summary>
//        /// Writes to the WaveStream. Not Supported.
//        /// </summary>
//        public override void Write(byte[] buffer, int offset, int count) {
//            throw new NotSupportedException("Can't write to a WaveFormatString");
//        }

//        /// <summary>
//        /// Recommends a number of bytes to read, given a desired number of
//        /// milliseconds. Use this in subsequent calls to Read, to ensure that
//        /// full blocks are read
//        /// </summary>
//        /// <param name="milliseconds">Number of milliseconds desired</param>
//        /// <returns>Number of bytes to read</returns>
//        public virtual int GetReadSize(int milliseconds) {
//            int bytes = (int)((WaveFormat.AverageBytesPerSecond / 1000.0) * milliseconds);
//            if ((bytes % BlockAlign) != 0) {
//                // Return the upper BlockAligned
//                bytes = bytes + BlockAlign - (bytes % BlockAlign);
//            }
//            return bytes;
//            //return WaveFormat.ConvertLatencyToByteSize(milliseconds);
//        }

//        /// <summary>
//        /// The block alignment for this wavestream. Do not modify the Position
//        /// to anything that is not a whole multiple of this value
//        /// </summary>
//        public virtual int BlockAlign {
//            get {
//                return WaveFormat.BlockAlign;
//            }
//        }

//        /// <summary>
//        /// Moves forward or backwards the specified number of seconds in the stream
//        /// </summary>
//        /// <param name="seconds">Number of seconds to move, can be negative</param>
//        public void Skip(int seconds) {
//            lock (this) {
//                long newPosition = Position + WaveFormat.AverageBytesPerSecond * seconds;
//                if (newPosition > Length)
//                    Position = Length;
//                else if (newPosition < 0)
//                    Position = 0;
//                else
//                    Position = newPosition;
//            }
//        }

//        /// <summary>
//        /// The current position in the stream in Time format
//        /// </summary>
//        public TimeSpan CurrentTime {
//            get {
//                return TimeSpan.FromSeconds((double)Position / WaveFormat.AverageBytesPerSecond);
//            }
//            set {
//                Position = (long)(value.TotalSeconds * WaveFormat.AverageBytesPerSecond);
//            }
//        }

//        /// <summary>
//        /// Total length in real-time of the stream (may be an estimate for compressed files)
//        /// </summary>
//        public TimeSpan TotalTime {
//            get {

//                return TimeSpan.FromSeconds((double)Length / WaveFormat.AverageBytesPerSecond);
//            }
//        }

//        /// <summary>
//        /// Whether the WaveStream has non-zero sample data at the current position for the 
//        /// specified count
//        /// </summary>
//        /// <param name="count">Number of bytes to read</param>
//        public virtual bool HasData(int count) {
//            return Position < Length;
//        }
//    }
//}


